// 数据库操作
const mongoose = require("mongoose");
// hash密码
const bcrypt = require("bcrypt");
// 对象规则验证
const Joi = require("joi");
const _ = require("lodash");

// 模型规则类
const { Schema } = mongoose;

// 用户集合规则
const UserSchema = new Schema(
  {
    // 昵称
    username: {
      type: String,
      required: true,
      minlength: 2,
      maxlength: 30,
    },
    // 邮件
    email: {
      type: String,
      required: true,
      unique: true,
    },
    // 密码
    password: {
      type: String,
      required: true,
    },
    // 头像
    avatar: {
      type: String,
      default: null,
    },
  },
  { versionKey: false }
);

// 用户集合类
const User = mongoose.model("User", UserSchema);

// 定义对象验证规则
const userRules = {
  username: Joi.string()
    .min(2)
    .max(30)
    .required()
    .error(new Error("用户名最小长度为2，最大为30")),
  email: Joi.string()
    .regex(/^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/)
    .required()
    .error(new Error("邮箱不符合验证规则")),
  password: Joi.string()
    .required()
    .regex(/^[a-zA-Z0-9]{3,30}$/)
    .error(new Error("密码只能包含字母、数字")),
};

// 注册数据格式校验
const validateUser = (user) => {
  return Joi.validate(user, userRules, {
    // 检测到所有错误
    abortEarly: false,
    // 允许对象包含被忽略的未知键
    allowUnknown: true,
  });
};

// 登录数据格式校验
const validateLogin = (user) => {
  const schema = _.pick(userRules, ["email", "password"]);
  // 验证
  return Joi.validate(user, schema, {
    // 检测到错误立即返回
    abortEarly: true,
  });
};

User.findOne({ email: "1518372870@qq.com" }).then(async (result) => {
  if (result == null) {
    // 生成盐
    const salt = await bcrypt.genSalt(10);
    // 使用盐对密码进行加密
    const password = await bcrypt.hash("123", salt);

    User.create({
      username: "陈伟东",
      email: "1518372870@qq.com",
      password: password,
      avatar: null,
    });
  }
});

// 导出对象
module.exports = {
  User,
  userRules,
  validateUser,
  validateLogin,
};
